from django.db.models.signals import post_save, post_delete, pre_save
from django.dispatch import receiver
from .models import OPCUASubscription, MQTTSubscription
from .tasks import sync_opcua_subscription, sync_mqtt_subscription
import logging

logger = logging.getLogger(__name__)

# OPC UA 订阅信号处理
@receiver(post_save, sender=OPCUASubscription)
def handle_opcua_subscription_save(sender, instance, created, **kwargs):
    """处理 OPC UA 订阅保存后的操作"""
    try:
        if instance.is_active:
            sync_opcua_subscription.delay(
                subscription_id=instance.id,
                node_id=instance.node_id,
                server_url=instance.data_source.connection_string
            )
            logger.info(f"已触发 OPC UA 订阅同步任务 - ID: {instance.id}, 节点: {instance.node_id}")
        else:
            # 如果订阅被禁用，取消相关任务
            sync_opcua_subscription.delay(
                subscription_id=instance.id,
                action='cancel'
            )
            logger.info(f"已触发 OPC UA 订阅取消任务 - ID: {instance.id}")
    except Exception as e:
        logger.error(f"处理 OPC UA 订阅保存失败 - ID: {instance.id}, 错误: {str(e)}", exc_info=True)

@receiver(post_delete, sender=OPCUASubscription)
def handle_opcua_subscription_delete(sender, instance, **kwargs):
    """处理 OPC UA 订阅删除后的操作"""
    try:
        # 取消相关任务
        sync_opcua_subscription.delay(
            subscription_id=instance.id,
            action='cancel'
        )
        logger.info(f"已触发 OPC UA 订阅取消任务 - ID: {instance.id}")
    except Exception as e:
        logger.error(f"处理 OPC UA 订阅删除失败 - ID: {instance.id}, 错误: {str(e)}", exc_info=True)

# MQTT 订阅信号处理
@receiver(post_save, sender=MQTTSubscription)
def handle_mqtt_subscription_save(sender, instance, created, **kwargs):
    """处理 MQTT 订阅保存后的操作"""
    try:
        logger.info(f"MQTT订阅保存信号触发 - ID: {instance.id}, 是否新建: {created}, 是否启用: {instance.is_active}")
        
        # 只在创建新订阅时触发
        if created and instance.is_active:
            # 获取连接字符串
            broker_url = instance.data_source.connection_string
            logger.info(f"准备启动MQTT订阅任务 - ID: {instance.id}, Topic: {instance.topic}, Broker: {broker_url}")
            
            # 启动同步任务
            task = sync_mqtt_subscription.delay(
                subscription_id=instance.id,
                topic=instance.topic,
                broker_url=broker_url
            )
            logger.info(f"MQTT订阅任务已启动 - ID: {instance.id}, Task ID: {task.id}")
    except Exception as e:
        logger.error(f"处理MQTT订阅保存失败 - ID: {instance.id}, 错误: {str(e)}", exc_info=True)

@receiver(post_delete, sender=MQTTSubscription)
def handle_mqtt_subscription_delete(sender, instance, **kwargs):
    """处理 MQTT 订阅删除后的操作"""
    try:
        logger.info(f"MQTT订阅删除信号触发 - ID: {instance.id}")
        # 取消相关任务
        task = sync_mqtt_subscription.delay(
            subscription_id=instance.id,
            action='cancel'
        )
        logger.info(f"MQTT订阅取消任务已启动 - ID: {instance.id}, Task ID: {task.id}")
    except Exception as e:
        logger.error(f"处理MQTT订阅删除失败 - ID: {instance.id}, 错误: {str(e)}", exc_info=True)

# 数据源变更前的检查
@receiver(pre_save, sender=OPCUASubscription)
def check_opcua_datasource_change(sender, instance, **kwargs):
    """检查 OPC UA 订阅的数据源是否变更"""
    try:
        if instance.id:  # 只在更新时检查
            old_instance = OPCUASubscription.objects.get(id=instance.id)
            if old_instance.data_source_id != instance.data_source_id:
                # 数据源发生变更，需要重新同步
                sync_opcua_subscription.delay(
                    subscription_id=instance.id,
                    action='cancel'
                )
                logger.info(f"OPC UA 订阅数据源已变更 - ID: {instance.id}")
    except Exception as e:
        logger.error(f"检查 OPC UA 数据源变更失败 - ID: {instance.id}, 错误: {str(e)}", exc_info=True)

@receiver(pre_save, sender=MQTTSubscription)
def check_mqtt_datasource_change(sender, instance, **kwargs):
    """检查 MQTT 订阅的数据源是否变更"""
    try:
        if instance.id:  # 只在更新时检查
            old_instance = MQTTSubscription.objects.get(id=instance.id)
            if old_instance.data_source_id != instance.data_source_id:
                # 数据源发生变更，需要重新同步
                sync_mqtt_subscription.delay(
                    subscription_id=instance.id,
                    action='cancel'
                )
                logger.info(f"MQTT 订阅数据源已变更 - ID: {instance.id}")
    except Exception as e:
        logger.error(f"检查 MQTT 数据源变更失败 - ID: {instance.id}, 错误: {str(e)}", exc_info=True) 